package org.liujing.jsw.client.ui;

import com.google.gwt.user.client.ui.*;
import com.google.gwt.user.client.*;
import org.liujing.jsw.client.ui.plaf.*;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.*;
import java.util.*;

public class RepaintManager implements Command{
	
	private static boolean commandReady = false;
	private static RepaintManager validateCommand = new RepaintManager();
	static List<Container> invalidComponents;
	
	public static void addInvalidComponent(JComponent invalidComponent) 
    {
        Container validateRoot = null;

	/* Find the first JComponent ancestor of this component whose
	 * isValidateRoot() method returns true.  
	 */
        for(JComponent c = invalidComponent; c != null && (c instanceof JComponent); c = c.getParent()) {
			//if ((c instanceof CellRendererPane) || (c.getPeer() == null)) {
			//return;
			//}
			if ( ((c instanceof Container) &&  ((Container)c).isValidateRoot())
				&& c.getParent() == null) {
				validateRoot = (Container)c;
				break;
			}
		}
        
		/* There's no validateRoot to apply validate to, so we're done.
		 */
		if (validateRoot == null) {
			return;
		}

		/* If the validateRoot and all of its ancestors aren't visible
		 * then we don't do anything.  While we're walking up the tree
		 * we find the root Window or Applet.
		 */
		JComponent root = null;
	
		for(JComponent c = validateRoot; c != null; c = c.getParent() ) {
			if(c.getParent() == null)
				break;
			if (!c.isVisible() )
				return;
		}
	   
		/* Lazily create the invalidateComponents vector and add the
		 * validateRoot if it's not there already.  If this validateRoot
		 * is already in the vector, we're done.
		 */
		if (invalidComponents == null) {
			invalidComponents = new ArrayList<Container>();
		}
		else {
			int n = invalidComponents.size();
			for(int i = 0; i < n; i++) {
				if(validateRoot == invalidComponents.get(i)) {
					return;
				}
			}
		}
		invalidComponents.add(validateRoot);
		if(!commandReady){
			commandReady = true;
			DeferredCommand.addCommand(validateCommand);
		}
			
		/* Queues a Runnable that calls RepaintManager.validateInvalidComponents() 
		 * and RepaintManager.paintDirtyRegions() with SwingUtilities.invokeLater().
		 */
		//SystemEventQueueUtilities.queueComponentWorkRequest(root);
    }
    
    /** 
     * Validate all of the components that have been marked invalid.
     * @see #addInvalidComponent
     */
    public void validateInvalidComponents() {
    	GWT.log("validateInvalidComponents()");
        java.util.List<Container> ic;
        //synchronized(this) {
            if(invalidComponents == null) {
                return;
            }
            ic = invalidComponents;
            invalidComponents = null;
        //}
        int n = ic.size();
        for(int i = 0; i < n; i++) {
            ic.get(i).validate();
        }
    }
    
    public void execute () {
    	commandReady = false;
    	validateInvalidComponents();
    }
}
